/*
-----------------------------------------------------------------------------
This source file is part of DIVA
The project of Engineering Lab, dept. of CSIE, NTNU.

Copyright (c) 2000-2006 The Engineering Lab, dept. of CSIE, NTNU.
-----------------------------------------------------------------------------
Filename:    OgreVM.h
date:		2007/07/04
Description: 
	A completed VM should contains 2 parts.One(DIVA_AbstractVM) is VM interface,another(OgreVM) is VM animation(or 3D effect)

	In DIVA_AbstractVM.h,we account what interface a VM should implements.
	And in this file,we account what 3D effect can be used,these effect will be different according to 3D Engine.

	for exam,this is Ogre 3d Engine and this header file defines which Ogre 3D effect we can use in our VM.
-----------------------------------------------------------------------------

修改日期 : 2008/10/20
修改者 : hyt
Description :
    (1)

*/

/*------------------------------------------------------------*/
#ifndef _OGRE_VM_H_
#define	_OGRE_VM_H_
/*------------------------------------------------------------*/

#include <Ogre.h>
#include <OgreAxisAlignedBox.h>

//using namespace Ogre;
	
class OgreVM{
	public:
	
	OgreVM();
	~OgreVM();

	/** return the scene node of this VM */
	virtual Ogre::SceneNode* getSceneNode(void);

	/** return the VM's parent scene node */
	virtual Ogre::SceneNode* getParentSceneNode(void);

	/** return the VM's parent scene node */
	virtual void setParentSceneNode(Ogre::SceneNode *);

	/** return the name of the scenenode of this VM */
	virtual std::string getSceneNodeName() ;

	/** set the position (related to its parent scene node, which is assigned by DIVA) of this VM.
	    In normal cases, this method set the scene node's positions. However, it may be overridden 
		to return what VM wants to return */
	virtual void setPosition(Ogre::Vector3); 

	/** set the position (related to its parent scene node, which is assigned by DIVA) of this VM.
	    In normal cases, this method set the scene node's positions. However, it may be overridden 
		to return what VM wants to return */
	virtual void setPosition(Ogre::Real x, Ogre::Real y, Ogre::Real z){
		setPosition(Ogre::Vector3(x, y, z));
	}

	/** return the position related to its parent scene node (VM) @note only dummyVM will override this method */
	virtual Ogre::Vector3 getPosition();

	/** return the world position of this VM @note only dummyVM will override this method */
	virtual Ogre::Vector3 getWorldPosition();



	/** set the scale of the scene node. @remarks scale the scene node may not scale the child scene node 
	    depending on whether the child scene node is set to be scalable. Properties such as the relative positions
		to parent scene node will be scaled.
	*/
	virtual void setSceneNodeScale(Ogre::Vector3);
	/** set the scale of the scene node. @remarks scale the scene node may not scale the child scene node 
	    depending on whether the child scene node is set to be scalable. Properties such as the relative positions
		to parent scene node will be scaled.
	*/
	void setSceneNodeScale(Ogre::Real x, Ogre::Real y, Ogre::Real z){
		setSceneNodeScale(Ogre::Vector3(x, y, z));
	}
	/** set the scale of the scene node. @remarks scale the scene node may not scale the child scene node 
	    depending on whether the child scene node is set to be scalable. Properties such as the relative positions
		to parent scene node will be scaled.
	*/
	void setSceneNodeScale(Ogre::Real x){
		setSceneNodeScale(Ogre::Vector3(x, x, x));
	}

	/** scale the major scene node to the absolute size */
	void scaleSceneNodeToAbsSize(Ogre::Vector3); 
	
	
	/** return the scale of the scenenode of this VM */
	Ogre::Vector3 getSceneNodeScale();

	/** set the scale of VM's body. This method is usually overridden. In many cases, the meshes of a VM do not attach
	   to VM's main scene node because the meshes do not want to be scaled when major scene node is scaled. */
	virtual void setBodyScale(Ogre::Vector3)=0 ;

	/** set the scale of VM's body. This method is usually overridden. In many cases, the meshes of a VM do not attach
	   to VM's main scene node because the meshes do not want to be scaled when major scene node is scaled. */
	void setBodyScale(Ogre::Real x, Ogre::Real y, Ogre::Real z ) { 
		setBodyScale(Ogre::Vector3(x,y,z));
	}

	/** set the scale of VM's body. This method is usually overridden. In many cases, the meshes of a VM do not attach
	   to VM's main scene node because the meshes do not want to be scaled when major scene node is scaled. */
	void setBodyScale(Ogre::Real x) {
		setBodyScale(Ogre::Vector3(x,x,x));
	}

	/* return the scale factoring of this VM's body, not major scene node */
	virtual Ogre::Vector3 getBodyScale() = 0 ;

	/** set the absolute size for wanted size. This method will compute the current size of VM's body and scale it 
	    to the size specified in the parameter */
	virtual void scaleBodyToAbsSize(Ogre::Vector3 abssize) ;

	/** set the absolute size of VM's body. This method will compute the current size of VM's body and scale it 
	    to the size specified in the parameter */
	void scaleBodyToAbsSize(Ogre::Real x, Ogre::Real y, Ogre::Real z) {
		scaleBodyToAbsSize(Ogre::Vector3(x,y,z));
	}
	
	/* return true if the body of the VM scale when setSceneNodeScale() is called */
	virtual bool isBodyScaleWrtSceneNode() = 0 ;
	

	void roll(Ogre::Real);	
	void showBoundingBox(bool);// show the bound box to represent being selected

	/** return the original mesh size of this VM (before scaling). This method should be overridden in each VM
	    because a VM can use many meshes as its body */
	virtual Ogre::Vector3 getOriginalBodySize() = 0 ;


	/** return the actual size of this VM. This method should be overridden by each VM  */
	virtual Ogre::Vector3 getActualSize() = 0 ;

	/**  傳進三個參數vm_yaw,vm_pitch,vm_roll為目前這個vm所希望轉到的x,y,z方向 */
	virtual void rotate(Ogre::Vector3 rotateTo);

	virtual void rotate(Ogre::Real x,Ogre::Real y,Ogre::Real z);
	
		
	/** get a new position for this class of VM */
	Ogre::Vector3 OgreVM::getNewPosition() ;

	


protected:
	static long int num;  //auto set vmname by number of VM
	int entityNum;
	Ogre::Vector3 position ;
	Ogre::SceneManager* _mgr;
	std::string _VMName;
	Ogre::SceneNode* _ParentSceneNode;
	Ogre::SceneNode* _SceneNode;
	std::string getNewUniqueName(std::string speciastr);	
	std::string getNewUniqueName();
	
};
/*------------------------------------------------------------*/
#endif	//#ifndef _OGRE_VM_H_